import { getUID, getToken, logout, getAnonymousToken } from "../func/index";
import { authService, getLoginUrl } from "./auth";
import { server, auth } from "../../reco.config";
import { transform } from "./promise";
import { getDefaultOptions, urlEncodeParams, fetch } from "./core.base";

const api = server.url;

export class Http {
  urlEncodeParams = urlEncodeParams;

  _defaultOptions;

  get _isLoginPage() {
    return false;
  }

  constructor() {
    this.resolveRequestOptions((this._defaultOptions = getDefaultOptions()));
  }

  // region request

  request(url , options) {
    return this.transformRequest(this.transformRequestInfo(url, "GET", options));
  }

  get(url, options) {
    return this.transformRequest(this.transformRequestInfo(url, "GET", options));
  }

  post(url, body, options) {
    return this.transformRequest(this.transformRequestInfo(url, "POST", options, body));
  }

  put(url, body, options) {
    return this.transformRequest(this.transformRequestInfo(url, "PUT", options, body));
  }

  delete(url, options) {
    return this.transformRequest(this.transformRequestInfo(url, "DELETE", options));
  }

  patch(url, body, options) {
    return this.transformRequest(this.transformRequestInfo(url, "PATCH", options, body));
  }

  head(url, options) {
    return this.transformRequest(this.transformRequestInfo(url, "HEAD", options));
  }

  options(url, options) {
    return this.transformRequest(this.transformRequestInfo(url, "OPTIONS", options)) ;
  }

  // endregion request

  // region transform

  transformRequestInfo(url, method, options, body) {
    const request = this.resolveUrl(this.transformUrl((url && url.url) ? url.url : url), this.formatUrlParams(options)),
      params = (url && url.url) ? Object.assign({ method: method }, url) : { method: method };

    delete params.url;

    this.resolveRequestHeaders(this._defaultOptions.headers);
    
    // request,
    //   Object.assign(options || (options = {}),
    //     this._defaultOptions.headers, params, options)
    var obj = {
      url: request,
      method: (params?params.method:'GET'),
      header: this._defaultOptions.headers,
      body:body
    };

    return obj;
  }

  transformRequest(input) {
    return this.transformResponse(this.isValidToken() 
      || !this.isAutoLogin() ? fetch(input) : authService.autoLogin(input), input);
  }


  formatUrlParams(options) {
    if (!options || (!options.search && !options.params)) return "";

    const search = this.formatUrlParam(options.search).toString(),
      params = this.formatUrlParam(options.params).toString();

    delete options.search, delete options.params;


    return search + (search && params ? "&" : "") + params;
  }

  formatUrlParam(params) {
    return typeof params === "object" ? this.urlEncodeParams(params) : (params||'');
  }

  transformUrl(url){
    return api + url;
  }

  resolveUrl(url, params) {
    const urls = url.split("?");

    if (urls.length > 1) params = urls[1] + params;

    return urls[0] + (params ? "?" : "") + params;
  }

  resolveRequestOptions(defaultOptions) {
    this.resolveRequestHeaders(defaultOptions.headers);
  }

  resolveRequestHeaders(headers) {
    const token = getToken() || getAnonymousToken();

    token ? (headers.Authorization = token) : (headers.Authorization=null);
  }

  transformResponse(response, input) {
    authService.cycle_refresh_token();

    const rs = { input: input },
      promise = new Promise((a, b) => {
        (rs.success = a), (rs.error = b);
        
        response.then(d => a(d))
                .catch(d=>{
                  b(d);
                  if (d.ExceptionMessage && d.ExceptionMessage.indexOf('证书') >= 0){
                    wx.removeStorageSync('Token');
                    wx.navigateTo({
                      url: '../binding/binding'
                    })
                  }
                })
          // .then(d => {
          //   if (d.ok && d.status === 204) return (rs.response = d), null;
          //   else if (d.ok || d.status === 400) return (rs.response = d).json();
          //   else if ((auth.autoLogin || auth.autoRefreshToken) && d.status !== 403 && d.status !== 500) this.refresh_token(rs);
          //   else b(rs.response = d);

          //   return Promise.reject(d.status === 500 ? null : authService.logoutResponse);
          // }, () => (this.refresh_token(rs), Promise.reject(auth.autoLogin || auth.autoRefreshToken ? null : authService.logoutResponse)))
      })

    return transform(promise, rs);
  }


  isValidToken(){
    return !!getToken() || this._isLoginPage || !!getAnonymousToken();
  }

  isAutoLogin() {
    return (auth.autoLogin && !!getUID()) || auth.anonymousLogin;
  }

  getSid() {

    return wx.getStorageSync("sid") || "";
  }

  getRid(){
    return wx.getStorageSync("rid") || "KGCD*FG98431SER-EWEW";
  }

  getUrlToken(){
    return `sid=${this.getSid()}&rid=${this.getRid()}`;
  }

  jump(isLogout) {
    // if (!this._isLoginPage) {
    //   logout(), router && router.push(`${getLoginUrl(isLogout)}`);
    // }
  }

  logout() {
    return this.jump(!0), this.transformResponse(Promise.reject({ Message: "系统已经退出！" }));
  }

  refresh_token(back) {
    if (auth.autoLogin || auth.autoRefreshToken) {
      authService[this.isAutoLogin() ? "autoLogin" : "refresh_token"](back.input)
        .then(r => ((back.response = r).ok ? r.json() : (back.error(r), Promise.reject(authService.logoutResponse))))
        .then(back.success,(d)=>{
          d && d.logout && this.jump()
        });
    }
  }

}

